#ifndef TRANSFORMER_LOGGER_HPP_3
#define TRANSFORMER_LOGGER_HPP_3

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include "transContentDefine.h"
#include "transContentErrorCode.h"

#ifdef MDEBUG

#define debug_enter() (logger::getInstance())->appendInfo(logger::LEVEL_INFO,  "Enter function: "__FUNCTION__)
#define debug_leave() (logger::getInstance())->appendInfo(logger::LEVEL_INFO,  "Leave function: "__FUNCTION__)
#define debug_record(level,...) (logger::getInstance())->appendDetail(__LINE__, __FUNCTION__, __FILE__, level, __VA_ARGS__)

//detail info
#define logd_info(...)	(logger::getInstance())->appendDetail(__LINE__, __FUNCTION__, __FILE__, logger::LEVEL_INFO, __VA_ARGS__)
#define logd_warm(...)	(logger::getInstance())->appendDetail(__LINE__, __FUNCTION__, __FILE__, logger::LEVEL_WARMMING, __VA_ARGS__)
#define logd_notice(...)	(logger::getInstance())->appendDetail(__LINE__, __FUNCTION__, __FILE__, logger::LEVEL_NOTICE, __VA_ARGS__)
#define	logd_error(...)	(logger::getInstance())->appendDetail(__LINE__, __FUNCTION__, __FILE__, logger::LEVEL_ERROR, __VA_ARGS__)
#define logd_fata_error(...)	(logger::getInstance())->appendDetail(__LINE__, __FUNCTION__, __FILE__, logger::LEVEL_FATA_ERROR, __VA_ARGS__)

//just info
#define log_info(...) (logger::getInstance())->appendInfo(logger::LEVEL_INFO, __VA_ARGS__)
#define log_warm(...)	(logger::getInstance())->appendInfo(logger::LEVEL_WARMMING, __VA_ARGS__)
#define log_notice(...)	(logger::getInstance())->appendInfo(logger::LEVEL_NOTICE, __VA_ARGS__)
#define	log_error(...)	(logger::getInstance())->appendInfo(logger::LEVEL_ERROR, __VA_ARGS__)
#define log_fata_error(...)	(logger::getInstance())->appendInfo(logger::LEVEL_FATA_ERROR, __VA_ARGS__)

#else

#define debug_enter()
#define debug_leave()
#define debug_record(level,...) 

#define logd_info(...)
#define logd_warm(...)
#define logd_notice(...)
#define	logd_error(...)
#define logd_fata_error(...)

#define log_info(...)
#define log_warm(...)
#define log_notice(...)
#define	log_error(...)
#define log_fata_error(...)

#endif //MDEBUG

class logger{
	public:
		//log level
		static const int LEVEL_INFO;		
		static const int LEVEL_NOTICE;
		static const int LEVEL_WARMMING;
		static const int LEVEL_ERROR;
		static const int LEVEL_FATA_ERROR;

		//log style
		static const int STYLE_HTML;
		static const int STYLE_TEXT;

	private:
		//css class constant value
		static const char* css_class_info;
		static const char* css_class_notice;
		static const char* css_class_warmming;
		static const char* css_class_error;
		static const char* css_class_fata_error;

		static logger* _instance;	
		//logstyle
		int mlogStyle;	
		//instance state
		int mState;
		//flush log file interval
		int flushInterval;
		//log file path and name
		char* mfilePath;

		FILE* logFile;
		//flush thread
		pthread_t flushThread;
		pthread_mutex_t mMutexWrite;

	private:
		/*************************************
		 * logger constructor should pass parameter as flow
		 * @param  [in] path: the logfile path and name may by no postfix
		 * @param  [in] logStyle: the log file content style
		 * if construct sucessfully, the state is ok, else is error
		 * ************************************/
		logger(const char* path, int logStyle);

		/********************************************
		 * the destrotor should free the path space and close file
		 * cancel the flush thread
		 * ******************************************/
		~logger();

		//open html file and input html header
		void init_logstyle_html();

		//open text file
		void init_logstyle_text();

		//close html file and input html ender
		void end_logstyle_html();

		void end_logstyle_text();

		void writeTimeStamp();

		//flush log into file
		void logflush();

		static void* flushLog(void* p);

	public:

		//get the logger instance, use signal pattern
		static logger* getInstance(const char* path="transformerContent", int logStyle = STYLE_HTML);

		//derefrence the logger instance
		static void releaseInstance();

		//get the filestate
		int getState();

		//return int not char* invalidate to despose the buffer
		int getLogFile(char* buffer, int len);

		int getLogStyle();

		int getFlushInterval();

		//append data with line etc
		int appendDetail(int line, const char* functionName, const char* sourceName, int level, const char* format,...);

		//append log info to output stream
		int appendInfo(int level, const char* format,...);


};
#endif //TRANSFORMER_LOGGER_HPP_3
